ARM platforms: Provide SDEI entry point validation
authorJeenu Viswambharan <[email protected]>
Thu, 19 Oct 2017 08:15:15 +0000 (09:15 +0100)
committerJeenu Viswambharan <[email protected]>
Mon, 13 Nov 2017 08:38:51 +0000 (08:38 +0000)
Provide a strong definition for plat_sdei_validate_sdei_entrypoint()
which translates client address to Physical Address, and then validating
the address to be present in DRAM.

Change-Id: Ib93eb66b413d638aa5524d1b3de36aa16d38ea11
Signed-off-by: Jeenu Viswambharan <[email protected]>
include/lib/aarch64/arch.h
include/lib/aarch64/arch_helpers.h
plat/arm/common/arm_common.c

index 16d12a3830ef2b6e4753f6a52e9c8a1ab84299bf..cb7dab7ff32a8b0a207056e4608df089302a18eb 100644 (file)
 
 #define MAKE_MAIR_NORMAL_MEMORY(inner, outer)  ((inner) | ((outer) << MAIR_NORM_OUTER_SHIFT))
 
+/* PAR_EL1 fields */
+#define PAR_F_SHIFT    0
+#define PAR_F_MASK     1
+#define PAR_ADDR_SHIFT 12
+#define PAR_ADDR_MASK  (BIT(40) - 1) /* 40-bits-wide page address */
+
 #endif /* __ARCH_H__ */
index 9c022ab5e64fa56ee9ddf29243730591afac382f..782343d67ff73cc3cecf94fe1b2e49dbb75bf37c 100644 (file)
@@ -155,6 +155,7 @@ DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1r)
 DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1w)
 DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0r)
 DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0w)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e2r)
 
 void flush_dcache_range(uintptr_t addr, size_t size);
 void clean_dcache_range(uintptr_t addr, size_t size);
index 1905c0b05efc88ea18b4d31d1ee1bb17ed104cc9..bf6397377c5f3ac7d086e61e9e024e58fe1829e9 100644 (file)
@@ -204,3 +204,51 @@ unsigned int plat_get_syscnt_freq2(void)
 }
 
 #endif /* ARM_SYS_CNTCTL_BASE */
+
+#if SDEI_SUPPORT
+/*
+ * Translate SDEI entry point to PA, and perform standard ARM entry point
+ * validation on it.
+ */
+int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
+{
+       uint64_t par, pa;
+       uint32_t scr_el3;
+
+       /* Doing Non-secure address translation requires SCR_EL3.NS set */
+       scr_el3 = read_scr_el3();
+       write_scr_el3(scr_el3 | SCR_NS_BIT);
+       isb();
+
+       assert((client_mode == MODE_EL2) || (client_mode == MODE_EL1));
+       if (client_mode == MODE_EL2) {
+               /*
+                * Translate entry point to Physical Address using the EL2
+                * translation regime.
+                */
+               ats1e2r(ep);
+       } else {
+               /*
+                * Translate entry point to Physical Address using the EL1&0
+                * translation regime, including stage 2.
+                */
+               ats12e1r(ep);
+       }
+       isb();
+       par = read_par_el1();
+
+       /* Restore original SCRL_EL3 */
+       write_scr_el3(scr_el3);
+       isb();
+
+       /* If the translation resulted in fault, return failure */
+       if ((par & PAR_F_MASK) != 0)
+               return -1;
+
+       /* Extract Physical Address from PAR */
+       pa = (par & (PAR_ADDR_MASK << PAR_ADDR_SHIFT));
+
+       /* Perform NS entry point validation on the physical address */
+       return arm_validate_ns_entrypoint(pa);
+}
+#endif